/*
 *      Copyright: Bernd Schubert <bschubert@ddn.com>
 *      License: GPLv3
*/


#ifndef __SD_H
#define __SD_H

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <ext2fs/ext2_fs.h>
#include <ext2fs/ext2fs.h>

#include "lustre_user.h"


/* The options structure */
typedef struct opts {
	char *fname;
	char *ost_data_file;
	char *mapping_file;
	char *outputdir;
	long long sb; 
	int block_size;
} opts_t;


typedef struct block block_t; // forward declaration only

/* A single directory entry */
typedef struct dentry {
	int64_t inode;
	int type;
	struct childs {
		// we should have only one child, but firstly, there are weird
		// double entries (exactly the same filename and inode number) 
		// in the directory entry and secondly in real live we will
		// see deleted entries
		int num; // number of childs
		block_t **child; // if dentry is a dir, it has a dir block
	} childs;
	char *name;
	struct dentry *next;

	// 1 for normal dir, 2 for symlinks after they are stable	
	int create_stage;  

	struct dentry *real_dir;
	struct dentry *symlink_next;
	struct dentry *link_waiter_next;
	block_t *block; 
} dentry_t;

/**
 * Information decoded from OST xattr and provided by our 
 * 'get_filter_fid'
 */
typedef struct ost_fid {
	time_t timestamp;
	uid_t uid;
	gid_t gid;
	dentry_t *dentry;
	struct lov_user_md_v1 fid;
} ost_fid_t;


/* A single block of dentries */
struct block {
	int64_t parent;		// inode from ".."
	int64_t dir_inode;	// inode from "."
	dentry_t *first;	// linked list of dentries
	char *name;		// diretory name of this block
	uint64_t number;		// number of this block
	long uid;	//owner of this block
	long gid;
	int walked;		// has this block been procesed?
	int mixed;		// are there multiple owners?
	block_t *tl_block;
	char *cwd;
};

/** 
 * The table of all blocks with dentries. Unless directories got too large, each
 * of these blocks represents a directory then. Secondary blocks for dirs that
 *  got too large DO NOT have "." and ".." entries
 */
typedef struct dir_block_table {
	block_t *table;
	uint64_t n_entries;
	uint64_t n_alloc;
} dir_block_table_t;

void read_ost_fid(char *fname);
void read_ost_mapping(char *fname);

#endif
